#include <translate.h>

// translate function
void translate(Graph_t &bgraph, PPPWGraph * pppgraph, int num_vertices) {
    vertex_iterator_t v, vend;
    int vid;
    weightmap_t weightmap = get(edge_weight, bgraph);
    for (tie(v, vend) = vertices(bgraph); v != vend ; v++) {
        pppgraph->nodes.push_back(new PPPNode(*v)); // add nodes to graph
        pppgraph->edges.push_back(new std::vector <PPPWEdge>()); // allocate edge vector for vertices
        vid = *v;
        out_edge_iterator_t e, eend;
        // go over all out edges 
        for (tie(e, eend) = out_edges(*v, bgraph) ; e != eend ; e++) {
            PPPWEdge E;
            E.to = (target(*e, bgraph));
            E.w = weightmap[*e];
            pppgraph->edges[vid]->push_back(E);
        }
    }
}

// buid ppp graph from generation file 
void buildGraph(std::string inFile, PPPWGraph * pppgraph, int num_vertices) {
    FILE * fp; // file pointer
    int curr; // current position
    int vid; // weight read

    fp = fopen(inFile.c_str(), "r");
    if (fp == NULL) {
        fprintf(stderr, "Cannot open file %s\n", inFile.c_str());
        exit(EXIT_FAILURE);
    }
    
    for (int i = 0 ; i < num_vertices ; i++) {
        pppgraph->nodes.push_back(new PPPNode(i)); // add num_vertices nodes to graph
        pppgraph->edges.push_back(new std::vector <PPPWEdge>()); // allocate edge vector for vertices
    }

    for (curr = 0 ; curr < num_vertices ; curr++) {
        for (int j = 0 ; j < num_vertices ; j++) {
            fscanf(fp, "%d", &vid);
            if (vid > 0) {
                PPPWEdge E; // there is an edge create it and fill in its parameters
                E.to = j;
                E.w = vid;
                pppgraph->edges[curr]->push_back(E); // push edge into vector
            } else if (vid < 0) {
                fprintf(stderr, "Negative valued edge found between vertices %d and %d\n", curr, j);
                exit(EXIT_FAILURE);
            }
        }
    }

    fclose(fp); fp = NULL;
}

// build a boost graph from the input generation file
void buildBoost(std::string inFile, Graph_t * graph, int num_vertices) {
    FILE * fp; // file pointer
    int curr; // current position
    int vid; // weight read
    edge_descriptor_t e; // edge descriptor for adding edges to graph 
    bool cond; // condition for add_edge

    fp = fopen(inFile.c_str(), "r");
    if (fp == NULL) {
        fprintf(stderr, "Cannot open file %s\n", inFile.c_str());
        exit(EXIT_FAILURE);
    }

    for (int i = 0 ; i < num_vertices ; i++) {
        add_vertex(*graph);
    }

    weightmap_t weightmap = get(edge_weight, *graph);
    for (curr = 0 ; curr < num_vertices ; curr++) {
        for (int j = 0 ; j < num_vertices ; j++) {
            fscanf(fp, "%d", &vid);
            if (vid > 0) {
                out_edge_iterator_t ve, eend;
                for (tie(ve, eend) = out_edges(j, *graph); ve != eend ; ve++) {
                    if (target(*ve, *graph) == curr) {
                        break;
                    }
                }
                if (ve == eend) {
                    tie(e, cond) = add_edge(curr, j, *graph);
                    weightmap[e] = vid;
                }
            } else if (vid < 0) {
                fprintf(stderr, "Negative valued edge found between vertices %d and %d\n", curr, j);
                exit(EXIT_FAILURE);
            }
        }
    }
    fclose(fp); fp = NULL;

}
